import { defineStore } from "pinia";
import type { RouteRecordRaw } from "vue-router";
import userInfoApi, { type UserData, type UserInfoData } from "@/api/userInfo";
import { getToken, setToken, removeToken } from "@/utils/token-utils";
import { staticRoutes, allAsyncRoutes, anyRoutes } from "@/router/routes";
import router from "@/router";
import { ElMessage } from "element-plus";
// 按需引入lodash
import cloneDeep from "lodash/cloneDeep";
interface UserInfoStoreStateData {
  token: string;
  userInfo: UserInfoData;
  menuRoutes: RouteRecordRaw[];
}

function filterAsyncRoutes(allAsyncRoutes: Array<RouteRecordRaw>, rolesName: string[]) {
  const result = allAsyncRoutes.filter((item) => {
    if (rolesName.includes(item.name as string)) {
      if (item.children && item.children.length) {
        item.children = filterAsyncRoutes(item.children, rolesName);
      }
      return true;
    }
  });
  return result;
}

// 动态添加
function addRoutes(allAsyncRoutes: Array<RouteRecordRaw>) {
  allAsyncRoutes.forEach((item) => {
    router.addRoute(item);
  });
}

// 清空路由
function removeRoutes() {
  const allRoutes = router.getRoutes();
  allRoutes.forEach((item) => {
    router.removeRoute(item.name as string);
  });
  addRoutes(staticRoutes);
}

export const useUserInfoStore = defineStore("userInfo", {
  state(): UserInfoStoreStateData {
    return {
      token: getToken() as string,
      userInfo: {
        routes: [],
        buttons: [],
        roles: [],
        name: "",
        avatar: "",
      },
      menuRoutes: staticRoutes,
    };
  },
  actions: {
    async login(userData: UserData) {
      try {
        const res = await userInfoApi.reqLogin(userData);
        ElMessage.success("登录成功");
        this.token = res.token;
        setToken(res.token);
      } catch (error) {
        ElMessage.error("登录失败");
        return Promise.reject(error);
      }
    },
    async getInfo() {
      try {
        const res = await userInfoApi.reqGetUserInfo();
        this.userInfo = res;
        // cloneDeep 深克隆防止修改原数组
        const userAsyncRouter = filterAsyncRoutes(cloneDeep(allAsyncRoutes), res.routes);
        addRoutes(userAsyncRouter.concat(anyRoutes));
        this.menuRoutes = staticRoutes.concat(userAsyncRouter, anyRoutes);
      } catch (error) {
        return Promise.reject(error);
      }
    },
    async reset() {
      Object.assign(this.userInfo, {
        routes: [],
        buttons: [],
        roles: [],
        name: "",
        avatar: "",
      });
      this.token = "";
      removeToken();
      removeRoutes();
    },
    async logOut() {
      try {
        await userInfoApi.reqLogout();
        this.reset();
      } catch (error) {
        return Promise.reject(error);
      }
    },
  },
});
